DynamoDBのテーブルにCSVファイルから一括でデータをimportしてみた
こんにちは、崔です。
CSVファイルのデータをDynamoDBのテーブルにimportしたいと思ったことはありませんか?
こちらのAWSの公式ブログにおいて、これを実装するCloudFormationのテンプレートが提供されていましたので、試してみました。
やってみた
上記ブログ内のリポジトリからテンプレートをダウンロードします。
CSVToDynamo.templateファイル内の AttributeName
の2箇所のパーティションキー名を uuid
から利用予定のパーティションキー名に変更します。
"Resources": { "DynamoDBTable":{ "Type": "AWS::DynamoDB::Table", "Properties":{ "TableName": {"Ref" : "DynamoDBTableName"}, "BillingMode": "PAY_PER_REQUEST", "AttributeDefinitions":[ { "AttributeName": "uuid", "AttributeType": "S" } ], "KeySchema":[ { "AttributeName": "uuid", "KeyType": "HASH" } ], "Tags":[ { "Key": "Name", "Value": {"Ref" : "DynamoDBTableName"} } ] } },
次にCloudFormationからこのテンプレートを選択します。
パラメーターに、
- CSVファイル名(FileName)
- CSVファイルをアップロードするS3バケット名(BucketName)
- DynamoDBのテーブル名(DynamoDBTableName)
を入力して、実行します。
CloudFormationが正常に終了すると、空のDynamoDBのテーブルとS3バケット、Lambdaファンクションが作成されます。
作成されたLambdaファンクションは次のものでした。
import json import boto3 import os import csv import codecs import sys s3 = boto3.resource('s3') dynamodb = boto3.resource('dynamodb') bucket = os.environ['bucket'] key = os.environ['key'] tableName = os.environ['table'] def lambda_handler(event, context): #get() does not store in memory try: obj = s3.Object(bucket, key).get()['Body'] except: print("S3 Object could not be opened. Check environment variable. ") try: table = dynamodb.Table(tableName) except: print("Error loading DynamoDB table. Check if table was created correctly and environment variable.") batch_size = 100 batch = [] #DictReader is a generator; not stored in memory for row in csv.DictReader(codecs.getreader('utf-8')(obj)): if len(batch) >= batch_size: write_to_dynamo(batch) batch.clear() batch.append(row) if batch: write_to_dynamo(batch) return { 'statusCode': 200, 'body': json.dumps('Uploaded to DynamoDB Table') } def write_to_dynamo(rows): try: table = dynamodb.Table(tableName) except: print("Error loading DynamoDB table. Check if table was created correctly and environment variable.") try: with table.batch_writer() as batch: for i in range(len(rows)): batch.put_item( Item=rows[i] ) except: print("Error executing batch_writer")
次のようなCSVを用意しました。最初のカラムには、パーティションキーを指定します。
"Id","Price","ProductCategory","Title","BicycleType","Brand","Color","Description","Authors","Dimensions","ISBN","InPublication","PageCount" "101","2","Book","Book 101 Title",,,,,"[ { ""S"" : ""Author1"" }]","8.5 x 11.0 x 0.5","111-1111111111","true","500" "102","20","Book","Book 102 Title",,,,,"[ { ""S"" : ""Author1"" }, { ""S"" : ""Author2"" }]","8.5 x 11.0 x 0.8","222-2222222222","true","600" "103","2000","Book","Book 103 Title",,,,,"[ { ""S"" : ""Author1"" }, { ""S"" : ""Author2"" }]","8.5 x 11.0 x 1.5","333-3333333333","false","600" "201","100","Bicycle","18-Bike-201","Road","Mountain A","[ { ""S"" : ""Red"" }, { ""S"" : ""Black"" }]","201 Description",,,,, "202","200","Bicycle","21-Bike-202","Road","Brand-Company A","[ { ""S"" : ""Green"" }, { ""S"" : ""Black"" }]","202 Description",,,,, "203","300","Bicycle","19-Bike-203","Road","Brand-Company B","[ { ""S"" : ""Red"" }, { ""S"" : ""Green"" }, { ""S"" : ""Black"" }]","203 Description",,,,, "204","400","Bicycle","18-Bike-204","Mountain","Brand-Company B","[ { ""S"" : ""Red"" }]","204 Description",,,,, "205","500","Bicycle","18-Bike-204","Hybrid","Brand-Company C","[ { ""S"" : ""Red"" }, { ""S"" : ""Black"" }]","205 Description",,,,,
これを先程のS3バケットにアップロードします。
すると、DynamoDBのテーブルにデータがロードされました。
まとめ
非常に簡単にCSVファイルをDynamoDBのテーブルにimportすることができました。
簡単に試せるので、まずはこの方法でimportできるか実行してみては如何でしょうか。